// Copyright (c) 2007, Brian Duff
// See LICENSE for license details.

package org.dubh.orablogs.ag;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;


public final class OrablogsService
{
  // Useful flag during testing that prevents accidental updates to the 
  // database.
  private static final boolean READ_ONLY = false;
  
  private EntityManagerFactory emf = Persistence.createEntityManagerFactory("OrablogsAggregator");

  public OrablogsService()
  {
  }

  private EntityManager getEntityManager()
  {
    return emf.createEntityManager();
  }

  public Object mergeEntity(Object entity)
  {
    if ( READ_ONLY ) return entity;
    final EntityManager em = getEntityManager();
    try
    {
      final EntityTransaction et = em.getTransaction();
      try
      {
        et.begin();
        em.merge(entity);
        et.commit();
      }
      finally
      {
        if (et != null && et.isActive())
        {
          entity = null;
          et.rollback();
        }
      }
    }
    finally
    {
      if (em != null && em.isOpen())
      {
        em.close();
      }
    }
    return entity;
  }

  public Object persistEntity(Object entity)
  {
    if ( READ_ONLY ) return entity;
    final EntityManager em = getEntityManager();
    try
    {
      final EntityTransaction et = em.getTransaction();
      try
      {
        et.begin();
        em.persist(entity);
        et.commit();
      }
      finally
      {
        if (et != null && et.isActive())
        {
          entity = null;
          et.rollback();
        }
      }
    }
    finally
    {
      if (em != null && em.isOpen())
      {
        em.close();
      }
    }
    return entity;
  }
  

  public BlogEntry findBlogEntryByGuid( Blog blogger, String guid )
  {
    return (BlogEntry) getEntityManager().createNamedQuery( "BlogEntries.findEntryByGuid")
      .setParameter( "guid", guid )
      .setParameter( "bloggerId", blogger.getId() )
      .getSingleResult();
  }

  public Blog findBloggerById( int id )
  {
    return (Blog) getEntityManager().createNamedQuery( "Bloggers.findById" )
      .setParameter( "id", id )
      .getSingleResult();
  }

  /** <code>select o from BlogEntries o</code> */
  public List<BlogEntry> queryBlogEntriesFindAll()
  {
    return getEntityManager().createNamedQuery("BlogEntries.findAll").getResultList();
  }

  public void removeBlogEntries(BlogEntry blogEntries)
  {
    if ( READ_ONLY ) return;
    final EntityManager em = getEntityManager();
    try
    {
      final EntityTransaction et = em.getTransaction();
      try
      {
        et.begin();
        blogEntries = em.find(BlogEntry.class, blogEntries.getGuid());
        em.remove(blogEntries);
        et.commit();
      }
      finally
      {
        if (et != null && et.isActive())
        {
          et.rollback();
        }
      }
    }
    finally
    {
      if (em != null && em.isOpen())
      {
        em.close();
      }
    }
  }

  /** <code>select o from Bloggers o</code> */
  public List<Blog> queryBloggersFindAll()
  {
    return getEntityManager().createNamedQuery("Bloggers.findAll").getResultList();
  }

  public void removeBloggers(Blog bloggers)
  {
    if ( READ_ONLY ) return;
    final EntityManager em = getEntityManager();
    try
    {
      final EntityTransaction et = em.getTransaction();
      try
      {
        et.begin();
        bloggers = em.find(Blog.class, bloggers.getId());
        em.remove(bloggers);
        et.commit();
      }
      finally
      {
        if (et != null && et.isActive())
        {
          et.rollback();
        }
      }
    }
    finally
    {
      if (em != null && em.isOpen())
      {
        em.close();
      }
    }
  }
}
